﻿using System.Linq;
using CoreEx.Database.Metadata;
using CoreEx.Database.Metadata.Generation;
using LinFu.IoC.Configuration;

namespace CoreEx.Database.MetaData.Implementation.Generation
{
    /// <summary>
    /// Inspects a <see cref="TableInfo"/> instances 
    /// to determine if the table represents a link table in a "many to many" relationship.
    /// </summary>
    [Implements(typeof(ILinkTableInspector))]
    public class LinkTableInspector : ILinkTableInspector
    {
        /// <summary>
        /// Determines if the <paramref name="tableInfo"/> represents a link table.
        /// </summary>
        /// <param name="tableInfo">The <see cref="TableInfo"/> instance to inspect.</param>
        /// <returns><b>true</b> if the <paramref name="tableInfo"/> represents a link table, otherwise <b>false</b></returns>
        public bool IsLinkTable(TableInfo tableInfo)
        {
            //The requirement for a link table is that is contains only two 
            //foreignkeys and the two keys must also make up the primary key
            if (tableInfo.ForeignKeys.Count > 2)
                return false;
            var foreignKeyColumns =
                tableInfo.ForeignKeys.SelectMany(fki => fki.Columns).Select(fkc => fkc.ForeignColumnInfo);

            if (tableInfo.Columns.Values.Except(foreignKeyColumns).Count() > 0)
                return false;

            return foreignKeyColumns.Except(tableInfo.PrimaryKey.Columns).Count() == 0;
        }
    }
}
